<?php
/**********************************************************************************
WIKINDX: Bibliographic Management system.
Copyright (C)

This program is free software; you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program;
if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

The WIKINDX Team 2008
sirfragalot@users.sourceforge.net
**********************************************************************************/
/*****
* RESOURCEMUSING class
*
* Deal with resource's musings
*****/
class RESOURCEMUSING
{
// Constructor
	function RESOURCEMUSING($db, $vars)
	{
		$this->db = $db;
		$this->vars = $vars;
		include_once("core/session/SESSION.php");
		$this->session = new SESSION();
		include_once("core/messages/MESSAGES.php");
		$this->messages = new MESSAGES();
		include_once("core/messages/SUCCESS.php");
		$this->success = new SUCCESS();
		include_once("core/messages/ERRORS.php");
		$this->errors = new ERRORS();
		include_once("core/html/MISC.php");
		include_once("core/html/HTML.php");
		$this->html = new HTML($this->db);
		include_once("core/html/FORM.php");
		include_once("core/html/TABLE.php");
		include_once("core/template/TEMPLATE.php");
		$this->template = new TEMPLATE('content');
		include_once("core/resource/TEXTQP.php");
		$this->textqp = new TEXTQP($this->db, $this->vars);
		include_once("core/html/CLOSE.php");
		include_once("core/keyword/KEYWORD.php");
		$this->keyword = new KEYWORD($this->db);
	}
// Display resource's musings
	function view($resourceId)
	{
// Load icons
		include_once("core/icons/LOADICONS.php");
		$icons = new LOADICONS();
		$icons->getIconInfo("edit");
		$viewEditLink = $icons->editExists ? "imgLink" : "link";
		$icons->getIconInfo("add");
		$addLink = $icons->addExists ? "imgLink" : "link";
		$pString = MISC::b($this->messages->text("viewResource", "musings"));
		$thisUserId = $write = $this->session->getVar('setup_userId');
		$pString .= $write ? " " . MISC::a($addLink, $icons->add, 
			"index.php?action=musingEdit" . htmlentities("&resourceId=" . $resourceId)) 
			:
			FALSE;
		$recordset = $this->db->select(array('WKX_resource_musing', 'WKX_resource_musing_text'), 
			array(array('WKX_resource_musing.id' => 'musingId'), 'page_start', 'page_end', 'text', 
			'paragraph', 'section', 'chapter', 'addUserIdMusing', 'timestamp', 'musingPrivate', 
			array('musing_keywords' => 'keywords')), 
			" WHERE " . $this->db->formatField('WKX_resource_musing.resourceId') . '=' . 
			$this->db->tidyInput($resourceId) .  
			" AND " . $this->db->formatField('WKX_resource_musing.id') . '=' . 
			$this->db->formatField('WKX_resource_musing_text.id') .  
			" ORDER BY " . $this->db->tidyInputClause('page_start') . ", " . 
			$this->db->tidyInputClause('timestamp'));
		$numRows = $this->db->numRows($recordset);
		if(!$numRows && !$write)
			return FALSE;
		else if(!$numRows)
			return $pString .= MISC::br() . "&nbsp;" . MISC::br();
		$index = 0;
		if(array_key_exists("search", $this->vars) && $this->vars["search"] = 'highlight')
		{
			$searchTerms = explode(",", $this->session->getVar('search_highlight'));
			foreach($searchTerms as $term)
				$patterns[] = "/($term)(?!\S*\" \S*>)/i";
		}
		$somethingTodisplay = FALSE;
		include_once("core/cite/CITE.php");
		$cite = new CITE($this->db, $this->vars);
		$pString .= TABLE::tableStart(FALSE, 0, 0, 0, "left");
		while($row = $this->db->loopRecordSet($recordset))
		{
// Read only access
			if($this->session->getVar('setup_readOnly') && 
				(($row['musingPrivate'] == 'Y') || ($row['musingPrivate'] == 'G')))
				continue;
			else if(($row['musingPrivate'] == 'Y') && ($write != $row['addUserIdMusing']))
				continue;
// If 'G', this musing may be viewed by members of user groups of which $row[$addUserId] is a member
			else if($row['musingPrivate'] == 'G')
			{
				$recordset3 = $this->db->select(array('WKX_user_groups'), array('id'), 
					" WHERE FIND_IN_SET(" . $this->db->tidyInput($thisUserId) . ", 
					CONCAT(" . $this->db->formatfield('userIds') . ", ','))" . 
					" AND FIND_IN_SET(" . $this->db->tidyInput($row['addUserIdMusing']) . ", 
					CONCAT(" . $this->db->formatfield('userIds') . ", ','))");
				if(!$this->db->numRows($recordset3))
					continue;
			}
// Else, musing is public
			$somethingTodisplay = TRUE;
			$class = $index % 2 ? 'alternate2' : 'alternate1';
			$detail = $this->getDetails($row);
			$keywordText = '';
			if($row['keywords'])
			{
// Find keywords for this metadata
				$keywordIds = explode(",", $row['keywords']);
				$keywords = $conditions = array();
				foreach($keywordIds as $keywordId)
					$conditions[] = $this->db->tidyInput($keywordId);
				$condition = " WHERE " . $this->db->formatField('id') ."=" . 
					join(" OR " . $this->db->formatField('id') ."=", $conditions);
				$recordset2 = $this->db->select(array('WKX_keyword'), array('id', 'keyword'), 
					$condition . " ORDER BY " . $this->db->tidyInputClause('keyword'));
				$keywordText = MISC::br() . 
					MISC::b($this->messages->text("resources", "keywords") . ":&nbsp;&nbsp;");
				while($rowKeywords = $this->db->loopRecordSet($recordset2))
				{
					$keywords[] = $this->keyword->getKeywordLinkMeta($resourceId, $rowKeywords['id'], 
						$this->html->dbToHtmlTidy($rowKeywords['keyword']));
				}
				if(!empty($keywords))
					$keywordText .= join(", ", $keywords);
			}
			include_once("core/user/USER.php");
			$user = new USER($this->db);
			$userAddEdit = $user->displayUserAddEdit($row['addUserIdMusing']);
			$pString .= TABLE::trStart();
			$entry = $this->html->dbToHtmlTidy($row['text']);
			if(isset($patterns))
			{
				$url = FALSE;
/**
* Temporarily replace any URL - works for just one URL in the output string.
*/
				if(preg_match("/(<a.*>)/Ui", $entry, $match))
				{
					$url = preg_quote($match[1], '/');
					$entry = preg_replace("/$url/", "OSBIB__URL__OSBIB", $entry);
				}
// This double replace stops stops the search term 'ass' being used to replace the 'ass' in 'class'
			$entry = preg_replace($patterns, "W!I!K!I!N!D!X!$1W!I!K!I!N!D!X!", $entry);
			$entry = preg_replace("/W!I!K!I!N!D!X!(.*)W!I!K!I!N!D!X!/U", MISC::span("$1", "highlight"), $entry);
//			$entry = preg_replace($patterns, MISC::span("$1", "highlight"), $entry);
// Recover any URL
				if($url)
					$entry = str_replace("OSBIB__URL__OSBIB", $match[1], $entry);
			}
			else
				$entry = $detail . $entry;
			$pString .= TABLE::td($cite->parseCitations($entry, 'html') . $keywordText . $userAddEdit, $class);
			if($write == $row['addUserIdMusing'])
			{
				$editLink = MISC::a("$viewEditLink", "&nbsp;" . $icons->edit . 
				"&nbsp;", "index.php?action=musingEdit" . 
				htmlentities("&resourceId=" . $resourceId . "&musingId=" . $row['musingId']));
				$pString .= TABLE::td($editLink, $class, "right", "top");
			}
			else
				$pString .= TABLE::td("&nbsp;", $class, "right", "top");
			$pString .= TABLE::trEnd();
			$index++;
		}
// display nothing if readOnly and nothing to display
		if(!$somethingTodisplay && $this->session->getVar('setup_readOnly'))
			return FALSE;
		$pString .= TABLE::tableEnd();
		$pString .= MISC::br() . "&nbsp;" . MISC::br();
		return $pString;
	}
// display the editing form:
	function editDisplay()
	{
		$this->checkInput();
		$this->template->setVar('heading', $this->messages->text("heading", "musings"));
		$hidden = FORM::hidden("resourceId", $this->vars['resourceId']);
		$page_start = $page_end = $db_paragraph = $db_section = $db_chapter = $text = $rowKeywords = 
			$private = FALSE;
// are we editing or adding?
		if(array_key_exists('musingId', $this->vars))
		{
			$hidden .= FORM::hidden("musingId", $this->vars['musingId']);
			$recordset = $this->db->select(array('WKX_resource_musing', 'WKX_resource_musing_text'), 
				array(array('WKX_resource_musing.id' => 'musingId'), 'page_start', 'page_end', 'text', 
				'paragraph', 'section', 'chapter', 'musing_keywords', 'musingPrivate'), 
				" WHERE WKX_resource_musing.id=" . $this->vars['musingId'] . 
				" AND WKX_resource_musing.id=WKX_resource_musing_text.id");
			$row = $this->db->fetchRow($recordset);
			$rowKeywords = $row['musing_keywords'];
			$page_start = $this->html->dbToFormTidy($row['page_start']);
			$page_end = $this->html->dbToFormTidy($row['page_end']);
			$db_paragraph = $this->html->dbToFormTidy($row['paragraph']);
			$db_section = $this->html->dbToFormTidy($row['section']);
			$db_chapter = $this->html->dbToFormTidy($row['chapter']);
			$text = $this->html->dbToFormTidy($row['text']);
			$private = $row['musingPrivate'];
		}
		else
			$private = 'N';
		$pString = TABLE::tableStart(FALSE, 0, 0, 0, "left");
		$pString .= TABLE::trStart();
		$pString .= $this->textqp->displayKeywordForm('musing', $rowKeywords);
		$pString .= TABLE::trEnd();
		$pString .= TABLE::tableEnd();
// Encapsulating cell from body.tpl
		$pString .= TABLE::tdEnd() . TABLE::trEnd() . TABLE::trStart() . TABLE::tdStart();

		$pString .= TABLE::tableStart(FALSE, 0, 0, 0, "left");
		$pString .= TABLE::trStart();
		$td = $hidden . FORM::textInput($this->messages->text("resources", "page"), 
			"musingPageStart", $page_start, 6, 5);
		$td .= " - " . FORM::textInput(FALSE, "musingPageEnd", $page_end, 6, 5);
		$pString .= TABLE::td($td);
		$pString .= TABLE::td(FORM::textInput($this->messages->text("resources", "paragraph"), 
			"musingParagraph", $db_paragraph, 11, 10));
		$pString .= TABLE::td(FORM::textInput($this->messages->text("resources", "section"), 
			"musingSection", $db_section, 20));
		$pString .= TABLE::td(FORM::textInput($this->messages->text("resources", "chapter"), 
			 "musingChapter", $db_chapter, 20));
		$pString .= TABLE::trEnd();
		$pString .= TABLE::tableEnd();
		$pString .= TABLE::tdEnd() . TABLE::trEnd() . TABLE::trStart() . TABLE::tdStart();
		
		$pString .= TABLE::tableStart(FALSE, 0, 0, 0, "left");
		$pString .= TABLE::trEnd();
		$pString .= TABLE::trStart();
		$pString .= TABLE::td(MISC::br() . "&nbsp;" . MISC::br());
		$pString .= TABLE::trEnd();
		$pString .= TABLE::trStart();
// Create citation link for this type
		include_once("core/cite/CITE.php");
		$citeLink = CITE::makeCiteLink('musing');
// The second parameter ('musingText') to textareaInput is the textarea name
		$pString .= TABLE::td(FORM::textareaInput($this->messages->text("resources", "musing"), 
			"musingText", $text, 80, 10) . $citeLink . MISC::br() . 
			$this->messages->text("hint", "format"));
		$pString .= TABLE::trEnd();
		$thisUserId = $write = $this->session->getVar('setup_userId');
		$recordset3 = $this->db->select(array('WKX_user_groups'), array('id'), 
					" WHERE FIND_IN_SET(" . $this->db->tidyInput($thisUserId) . ", 
					CONCAT(" . $this->db->formatfield('userIds') . ", ','))");
		if($this->db->numRows($recordset3))
		{
			$privateArray = array('N' => $this->messages->text("resources", "public"), 
				'Y' => $this->messages->text("resources", "private"), 
				'G' => $this->messages->text("resources", "availableToGroups"));
			$privateForm = FORM::selectedBoxValue($this->messages->text("resources", "musingPrivate"), 
				"private", $privateArray, $private, 3);
		}
		else
		{
			$privateArray = array('N' => $this->messages->text("resources", "public"), 
				'Y' => $this->messages->text("resources", "private"));
			$privateForm = FORM::selectedBoxValue($this->messages->text("resources", "musingPrivate"), 
				"private", $privateArray, $private, 2);
		}
		$pString .= TABLE::trStart();
		$pString .= TABLE::td(MISC::p($privateForm . "&nbsp;&nbsp;" . FORM::formSubmit("Proceed")));
		$pString .= TABLE::trEnd();
		$pString .= TABLE::tableEnd();
// Encapsulating cell from body.tpl
		$pString .= TABLE::tdEnd() . TABLE::trEnd();
		$this->template->setVar('formStart', FORM::formHeader("musingEdit"));
		$this->template->setVar('body', $pString);
		$this->template->setVar('formEnd', FORM::formEnd());
		return $this->template->process();
	}
// write to the database.
// if there is no 'musingId' input, we are adding a new musing.  Otherwise, editing one.
	function edit()
	{
		if($this->session->getVar('resourceMusingLock'))
			$this->badInput($this->errors->text("done", "musing"));
		$this->checkInput();
		$userId = $this->session->getVar('setup_userId');
		if(!array_key_exists('keyword_ids', $this->vars))
			$this->vars['keyword_ids'] = array();
		if(array_key_exists('musingText', $this->vars) && $this->vars['musingText'])
			$keywordIds = $this->keyword->writeKeywordTable(array('keywords' => 
				$this->vars['keywords'], 'keyword_ids' => join(",", $this->vars['keyword_ids'])));
// insert?
		if(!array_key_exists('musingId', $this->vars))
		{
			if(!array_key_exists('musingText', $this->vars) || !$this->vars['musingText'])
				$this->badInput($this->errors->text("inputError", "missing"));
			if(isset($keywordIds) && $keywordIds)
			{
				foreach($keywordIds as $value)
				{
					if($value)
						$temp[] = $value;
				}
				if(isset($temp))
				{
					$fields[] = "musing_keywords";
					$values[] = implode(',', $temp);
				}
			}
			$addEdit = 'added';
			$fields[] = 'resourceId';
			$values[] = trim($this->vars['resourceId']);
			if(array_key_exists('musingPageStart', $this->vars) && $this->vars['musingPageStart'])
			{
				$fields[] = 'page_start';
				$values[] = trim(strtolower($this->vars['musingPageStart']));
				if(array_key_exists('musingPageEnd', $this->vars) && $this->vars['musingPageEnd'])
				{
					$fields[] = 'page_end';
					$values[] = trim(strtolower($this->vars['musingPageEnd']));
				}
			}
			if(array_key_exists('musingParagraph', $this->vars) && $this->vars['musingParagraph'])
			{
				$fields[] = 'paragraph';
				$values[] = trim(strtolower($this->vars['musingParagraph']));
			}
			if(array_key_exists('musingSection', $this->vars) && $this->vars['musingSection'])
			{
				$fields[] = 'section';
				$values[] = trim(strtolower($this->vars['musingSection']));
			}
			if(array_key_exists('musingChapter', $this->vars) && $this->vars['musingChapter'])
			{
				$fields[] = 'chapter';
				$values[] = trim(strtolower($this->vars['musingChapter']));
			}
			$this->db->insert('WKX_resource_musing', $fields, $values);
			$fields = $values = array();
			$fields[] = 'id';
			$values[] = $this->db->lastAutoId('WKX_resource_musing');
			$fields[] = 'text';
			$values[] = trim($this->vars['musingText']);
			if(array_key_exists('private', $this->vars) && ($this->vars['private'] == 'Y'))
			{
				$fields[] = 'musingPrivate';
				$values[] = 'Y';
			}
			else if(array_key_exists('private', $this->vars) && ($this->vars['private'] == 'G'))
			{
				$fields[] = 'musingPrivate';
				$values[] = 'G';
			}
			else
			{
				$fields[] = 'musingPrivate';
				$values[] = 'N';
			}
			$fields[] = 'timestamp';
			$values[] = $this->db->formatTimestamp();
			if($userId)
			{
				$fields[] = "addUserIdMusing";
				$values[] = $userId;
			}
			$this->db->insert('WKX_resource_musing_text', $fields, $values);
			$this->summary(1);
		}
// else edit/delete?
		else
		{
			$addEdit = 'edited';
			$checkKeywords = FALSE;
			if(isset($keywordIds) && $keywordIds)
			{
				$recordset = $this->db->select(array('WKX_resource_musing'), array('musing_keywords'), 
					" WHERE " . $this->db->formatfield('id') . "=" . 
					$this->db->tidyInput($this->vars['musingId']));
				$row = $this->db->fetchRow($recordset);
				if(!empty($row))
					$checkKeywords = array_diff(explode(",", $row['musing_keywords']), 
					$keywordIds);
			}
// if musingText is empty, delete the row
			if(!$this->vars['musingText'])
			{
				$addEdit = 'deleted';
				$this->db->delete('WKX_resource_musing', 
					"WHERE " . $this->db->formatField('id') . "=" . 
					$this->db->tidyInput($this->vars['musingId']));
				$this->db->delete('WKX_resource_musing_text', 
					"WHERE " . $this->db->formatField('id') . "=" . 
					$this->db->tidyInput($this->vars['musingId']));
				$this->db->optimize('WKX_resource_musing');
				$this->db->optimize('WKX_resource_musing_text');
				$this->summary(-1);
			}
			else
			{
				$addEdit = 'edited';
				$updateArray['text'] = trim($this->vars['musingText']);
				if(array_key_exists('private', $this->vars) && ($this->vars['private'] == 'Y'))
					$updateArray['musingPrivate'] = 'Y';
				else if(array_key_exists('private', $this->vars) && ($this->vars['private'] == 'G'))
					$updateArray['musingPrivate'] = 'G';
				else
					$updateArray['musingPrivate'] = 'N';
				$this->db->update('WKX_resource_musing_text', $updateArray, 
					"WHERE " . $this->db->formatField('id') . "=" . 
					$this->db->tidyInput($this->vars['musingId']));
				$updateArray = $nulls = array();
// page number lowercased in case roman numerals input!
				if(array_key_exists('musingPageStart', $this->vars) && $this->vars['musingPageStart'])
				{
					$updateArray['page_start'] = 
						trim(strtolower($this->vars['musingPageStart']));
					if(array_key_exists('musingPageEnd', $this->vars) && $this->vars['musingPageEnd'])
						$updateArray['page_end'] = 
							trim(strtolower($this->vars['musingPageEnd']));
					else
						$nulls[] = 'page_end';
				}
				else
				{
					$nulls[] = 'page_start';
					$nulls[] = 'page_end';
				}
				if(array_key_exists('musingParagraph', $this->vars) && $this->vars['musingParagraph'])
				{
					$updateArray['paragraph'] = 
						trim($this->vars['musingParagraph']);
				}
				else
					$nulls[] = 'paragraph';
				if(array_key_exists('musingSection', $this->vars) && $this->vars['musingSection'])
				{
					$updateArray['section'] = 
						trim($this->vars['musingSection']);
				}
				else
					$nulls[] = 'section';
				if(array_key_exists('musingChapter', $this->vars) && $this->vars['musingChapter'])
				{
					$updateArray['chapter'] = 
						trim($this->vars['musingChapter']);
				}
				else
					$nulls[] = 'chapter';
				if(isset($keywordIds) && $keywordIds)
				{
					foreach($keywordIds as $value)
					{
						if($value)
							$temp[] = $value;
					}
					if(isset($temp))
						$updateArray['musing_keywords'] = join(",", $temp);
				}
				else
					$nulls[] =  'musing_keywords';
				if(!empty($updateArray))
					$this->db->update('WKX_resource_musing', $updateArray, 
						"WHERE " . $this->db->formatField('id') . "=" . 
						$this->db->tidyInput($this->vars['musingId']));
				if(!empty($nulls))
					$this->db->updateNull('WKX_resource_musing', $nulls, 
						"WHERE " . $this->db->formatField('id') . "=" . 
						$this->db->tidyInput($this->vars['musingId']));
// update the musing timestamp
				$this->db->update('WKX_resource_musing_text', 
					array('timestamp' => $this->db->formatTimestamp()), 
					" WHERE " . $this->db->formatField('id') . "=" . 
					$this->db->tidyInput($this->vars['musingId']));
			}
			if($checkKeywords)
				$this->keyword->removeHanging2(join(",", $checkKeywords));
		}
// update resource timestamp
		$this->db->update('WKX_resource_timestamp', array('timestamp' => $this->db->formatTimestamp()), 
			" WHERE " . $this->db->formatField('id') . "=" . $this->db->tidyInput($this->vars['resourceId']));
// lock reload
		$this->session->setVar('resourceMusingLock', TRUE);
// email notification
		include_once("core/notify/NOTIFY.php");
		$notify = new NOTIFY($this->db);
		$notify->email($this->vars['resourceId']);
// send back to view this resource with success message
		include_once("core/resource/RESOURCEVIEW.php");
		$resource = new RESOURCEVIEW($this->db, $this->vars);
		new CLOSE($this->db, $resource->view($this->success->text("musings", " " . 
			$this->messages->text("misc", $addEdit) . " "), 'lastSolo'));
	}
// update or insert WKX_resource_summary
	function summary($incDec)
	{
// if row exists, update, else insert.
		$recordset = $this->db->select(array('WKX_resource_summary'), array('id'), 
			" WHERE " . $this->db->formatField('id') . "=" . 
			$this->db->tidyInput($this->vars['resourceId']));
		if($this->db->numRows($recordset))
			$this->db->updateSingle('WKX_resource_summary', $this->db->formatField('musings') . "=" . 
			"COALESCE(" . $this->db->formatField('musings') . "+" . 
			$this->db->tidyInput($incDec) . ", " . $this->db->tidyInput($incDec) . ")");
		else
			$this->db->insert('WKX_resource_summary', array('id', 'musings'), 
			array($this->vars['resourceId'], 1));
// if a decrement leaves nothing, delete row.
		$recordset = $this->db->select(array('WKX_resource_summary'), array('musings', 'paraphrases', 'quotes'), 
			" WHERE " . $this->db->formatField('id') . "=" . 
			$this->db->tidyInput($this->vars['resourceId']));
		$row = $this->db->fetchRow($recordset);
		if(!$row['musings'] && !$row['paraphrases'] && !$row['quotes'])
		{
			$this->db->delete('WKX_resource_summary', 
				"WHERE " . $this->db->formatField('id') . "=" . 
				$this->db->tidyInput($this->vars['resourceId']));
			$this->db->optimize('WKX_resource_summary');
		}
// update master summary table
		$this->db->updateSingle('WKX_database_summary', $this->db->formatField('totalMusings') . 
			"=" . $this->db->formatField('totalMusings') . "+" . $this->db->tidyInput($incDec));
	}
// Check we have appropriate input.  Page and comment are optional
	function checkInput()
	{
		if(!array_key_exists('resourceId', $this->vars) || !$this->vars['resourceId'])
			$this->badInput($this->errors->text("inputError", "missing"));
// editing a musing - musing must exist and must be valid userId
		if(array_key_exists('musingId', $this->vars) && $this->vars['musingId'])
		{
			$recordset = $this->db->select(array('WKX_resource_musing_text'), 
				array('id', 'addUserIdMusing'), 
				" WHERE " . $this->db->formatField('addUserIdMusing') . "=" . 
				$this->db->tidyInput($this->session->getVar('setup_userId')) . 
				" AND "  . $this->db->formatField('id') . "=" . 
				$this->db->tidyInput($this->vars['musingId']));
			if(!$this->db->numRows($recordset))
				$this->badInput($this->errors->text("inputError", "invalid"));
		}
	}
/** 
* Get metadata details such as pages, section etc.
*/
	function getDetails($row)
	{
			$page_start = $row['page_start'] ? $row['page_start'] : FALSE;
			$page_end = $row['page_end'] ? "-" . $row['page_end'] : FALSE;
			if($page_start && $page_end)
				$page_start = 'pp.' . $page_start;
			else if($page_start)
				$page_start = 'p.' . $page_start;
			$page = $page_start? $page_start . $page_end : FALSE;
			if($page)
				$details[] = $page;
			$paragraph = $row['paragraph'] ? $row['paragraph'] : FALSE;
			if($paragraph)
				$details[] = $this->messages->text("resources", "paragraph") . "&nbsp;" . $paragraph;
			$section = $row['section'] ? $row['section'] : FALSE;
			if($section)
				$details[] = $this->messages->text("resources", "section") . "&nbsp;" . $section;
			$chapter = $row['chapter'] ? $row['chapter'] : FALSE;
			if($chapter)
				$details[] = $this->messages->text("resources", "chapter") . "&nbsp;" . $chapter;
			return isset($details) ? MISC::b(MISC::i(join(", ", $details))) . "&nbsp;&nbsp;" : FALSE;
	}
// Error handling - send them back to view a resource.
	function badInput($error)
	{
		include_once("core/resource/RESOURCEVIEW.php");
		$resource = new RESOURCEVIEW($this->db, $this->vars);
		new CLOSE($this->db, $resource->view($error, 'lastSolo'));
	}
}
?>
